Skip to content

feat(config): exporter plugin loading via entry points for declarative config#5128

Open
MikeGoldsmith wants to merge 4 commits intoopen-telemetry:mainfrom
MikeGoldsmith:mike/config-exporter-plugin-loading
Open

feat(config): exporter plugin loading via entry points for declarative config#5128
MikeGoldsmith wants to merge 4 commits intoopen-telemetry:mainfrom
MikeGoldsmith:mike/config-exporter-plugin-loading

Conversation

@MikeGoldsmith
Copy link
Copy Markdown
Member

@MikeGoldsmith MikeGoldsmith commented Apr 20, 2026

Description

Extends exporter support in declarative file configuration to handle custom (plugin) exporters across all three signals, matching the spec's PluginComponentProvider mechanism.

Depends on #5131 (additional_properties support for generated models).

Solution

Each signal's factory function uses typed exporter config with additional_properties:

Signal Config type Registry Entry point group
Traces SpanExporterConfig _SPAN_EXPORTER_REGISTRY opentelemetry_traces_exporter
Metrics PushMetricExporterConfig _METRIC_EXPORTER_REGISTRY opentelemetry_metrics_exporter
Logs LogRecordExporterConfig _LOG_EXPORTER_REGISTRY opentelemetry_logs_exporter

Known exporter types (otlp_http, otlp_grpc, console) are checked via typed fields and their registries. Unknown plugin names from additional_properties are loaded via entry points.

Custom exporter example

tracer_provider:
  processors:
    - batch:
        exporter:
          my_custom_exporter: {}
[project.entry-points."opentelemetry_traces_exporter"]
my_custom_exporter = "my_package:MySpanExporterClass"

Remaining work

The OTLP factory functions still use typed attribute access (config.endpoint, etc.) internally. Converting them to accept raw dicts from the YAML loader is tracked in #5127.

Closes #5069

SpanExporter, LogRecordExporter, and PushMetricExporter are changed from
@DataClass to TypeAlias = dict[str, Any] in models.py, preserving unknown
exporter names as dict keys through the config pipeline.

Each signal's factory function (_create_span_exporter, _create_log_record_exporter,
_create_push_metric_exporter) now has a registry of known exporter names
(otlp_http, otlp_grpc, console) with fallback to load_entry_point for
unknown names via the opentelemetry_{traces,logs,metrics}_exporter
entry point groups.

_parse_headers in _common.py is updated to handle both NameStringValuePair
objects (typed config) and raw dicts (YAML path), making the full dict
path testable end-to-end.

Assisted-by: Claude Opus 4.6
The generated models are unchanged. Python dataclasses don't enforce
field types at runtime, so parent fields like BatchSpanProcessor.exporter
naturally accept raw dicts (from the YAML loader) alongside typed
instances. Tests updated to pass raw dicts consistently.

Assisted-by: Claude Opus 4.6
Use typed SpanExporterConfig, LogRecordExporterConfig, and
PushMetricExporterConfig with additional_properties from the
@_additional_properties decorator instead of raw dict iteration.
Known exporter types are checked via typed fields and their
registries. Unknown plugin names from additional_properties are
loaded via the opentelemetry_{traces,logs,metrics}_exporter
entry point groups.

Assisted-by: Claude Opus 4.6
@MikeGoldsmith MikeGoldsmith marked this pull request as ready for review April 29, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(config): generic plugin loading for OTLP exporters in declarative config

2 participants